package com.example.service.impl;

import com.example.common.UploadResult;
import com.example.config.ClientConfig;
import com.example.model.bo.FileLog;
import com.example.model.bo.SplitFileRecord;
import com.example.service.FileStoreService;
import com.example.utils.ContractAddressManager;
import com.example.utils.PropertyUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@NoArgsConstructor
@Data
public class FileStoreServiceImpl implements FileStoreService {
    public static final String RegisterAndFileStoreABI = com.example.utils.IOUtil.readResourceAsString("abi/RegisterAndFileStore.abi");
    private String RegisterAndFileStoreAddress = ContractAddressManager.getAddressFromContractNote("RegisterAndFileStore");

    public static final String UserRegistryABI = com.example.utils.IOUtil.readResourceAsString("abi/UserRegistry.abi");
    private String UserRegistryAddress = ContractAddressManager.getAddressFromContractNote("UserRegistry");


    @Autowired
    private Client client;


    AssembleTransactionProcessor txProcessor;

    String clientPri;

    @PostConstruct
    public void init() throws Exception {
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
    }


    @Override
    //拆分文件上链
    public UploadResult addSplitFile(SplitFileRecord input) throws Exception {
        //智能合约的参数列表
        List<Object> args = new ArrayList<>();
        //加载登录用户
        String userName = PropertyUtil.getUserName();
        AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + userName, ClientConfig.account_password);
        this.clientPri = client.getCryptoSuite().getCryptoKeyPair().getHexPrivateKey();
        //添加智能合约的参数信息
        Collections.addAll(args, client.getCryptoSuite().getCryptoKeyPair().getAddress(), input.getOrderInFile(), ClientConfig.account_username, input.getReceiverUserName(), input.getCid(), input.getFileName());
//        System.out.println(ClientConfig.account_address + "+" + input.getFileName());
//        System.out.println(client.getCryptoSuite().getCryptoKeyPair().getAddress() + "+" + input.getFileName());
        //形成交易
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
        TransactionResponse addRecord = this.txProcessor.sendTransactionAndGetResponse(this.RegisterAndFileStoreAddress, RegisterAndFileStoreABI, "addSplitFileRecord", args);
        //获取区块哈希
        String txHash = addRecord.getTransactionReceipt().getTransactionHash();
        String username = (String) addRecord.getReturnObject().get(1);
        //System.out.println("txHash:" + txHash);
        //封装智能合约返回的值
        UploadResult uploadResult = new UploadResult();
        uploadResult.setSender(username);
        uploadResult.setHash(txHash);
        return uploadResult;

    }

    @Override
    public void log(String fileName, String[] hashArr) throws Exception {
        List<Object> args = new ArrayList<>();
        String userName = PropertyUtil.getUserName();
        AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + userName, ClientConfig.account_password);
        this.clientPri = client.getCryptoSuite().getCryptoKeyPair().getHexPrivateKey();

        //设置上传时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String time = now.format(formatter);
        Collections.addAll(args, fileName, time, hashArr);
        //形成交易区块
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
        TransactionResponse addRecord = this.txProcessor.sendTransactionAndGetResponse(this.RegisterAndFileStoreAddress, RegisterAndFileStoreABI, "uploadFile", args);
    }

    @Override
    public List<FileLog> list() throws Exception {
        //智能合约函数对应的参数列表
        List<Object> args = new ArrayList<>();
        String userName = PropertyUtil.getUserName();
        AccountManager.loadP12Account(client, ClientConfig.account_keyfile_path + userName, ClientConfig.account_password);
        this.clientPri = client.getCryptoSuite().getCryptoKeyPair().getHexPrivateKey();
        //形成交易区块
        this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
        TransactionResponse addRecord = this.txProcessor.sendTransactionAndGetResponse(this.RegisterAndFileStoreAddress, RegisterAndFileStoreABI, "getAllFileBySender", args);
        //调用智能合约函数后返回的参数
        List<List<Object>> data = (List<List<Object>>) addRecord.getReturnObject().get(0);
        //历史上传记录的日志列表
        List<FileLog> fileLogs = new ArrayList<>();
        //封装查询到的日志信息
        for(List<Object> d : data){
            FileLog fileLog = new FileLog();
            fileLog.setFileName((String) d.get(0));
            fileLog.setUploadTime((String) d.get(1));
            fileLog.setHash((List<String>) d.get(2));
            fileLogs.add(fileLog);
        }

        //封装智能合约返回的值
        //List<FileLog> fileLogs  = (ArrayList<FileLog>) addRecord.getReturnObject().get(0);

        return fileLogs;
    }

}
